package org.wattdepot.cli.commands;

import java.util.List;
import javax.xml.datatype.XMLGregorianCalendar;
import org.wattdepot.client.BadXmlException;
import org.wattdepot.client.MiscClientException;
import org.wattdepot.client.NotAuthorizedException;
import org.wattdepot.client.ResourceNotFoundException;
import org.wattdepot.client.WattDepotClient;
import org.wattdepot.resource.property.jaxb.Property;
import org.wattdepot.resource.sensordata.jaxb.SensorData;
import org.wattdepot.util.tstamp.Tstamp;

/**
 * This class contains a command that prints out data for the day of the sensor.
 * 
 * Modified by David Mau.
 * @author Nathaniel Ashe
 * 
 */
public class SensorDayCommand implements WattDepotCliCommand {
  // Default client-server connection to use unless given one.
  private WattDepotClient client = new WattDepotClient(debug);

  /**
   * This constructor makes sure that the client really is connected to the server.
   * 
   * @param anotherClient Specifies if the user wants to use another WattDepot server
   * other than the default simulation one.
   */
  public SensorDayCommand( String anotherClient ) {
    // If another client is provided
    if ( anotherClient != null ) {
      client = new WattDepotClient( anotherClient );
    }
    
    // Stop right away if we cannot contact server.
    if (!client.isHealthy()) {
      System.out.println("Failed to connect to " + client.getWattDepotUri());
      return;
    }
    // Indicate successful connection.
    //System.out.println("Connected to " + client.getWattDepotUri());
  }

  /**
   * This method returns a String that has data for the day of a sensor.
   * 
   * Modified by David Mau.
   * Created by Nathaniel Ashe
   * 
   * @param args A list of arguments given to this command.
   * @return A string containing data for the day of the sensor.
   */
  public String doCommand(List<String> args) {
    String output = "";
    StringBuffer finalOutput = new StringBuffer(50);
    List<SensorData> data = null;
    List<Property> properties = null;
    XMLGregorianCalendar xmlTimeStamp = null;
    XMLGregorianCalendar xmlTimeStampEnd = null;

    if (args.size() > 2) {
      output = tooManyArguments;
      output = output.concat(cr);
      return output;
    }
    if (args.size() < 2) {
      output = missingArguments;
      output = output.concat(cr);
      return output;
    }
    
    String source = args.get(0);
    String timestamp = args.get(1);
    
    try {
      xmlTimeStamp = Tstamp.makeTimestamp(timestamp);
      xmlTimeStampEnd = Tstamp.makeTimestamp(timestamp);
      xmlTimeStampEnd = Tstamp.incrementDays(xmlTimeStampEnd, 1);
    }
    catch (Exception e) {
      output = badTimeStamp;
      output = output.concat(e.toString());
      output = output.concat(cr);
      return output;
    }

    try {
      data = client.getSensorDatas(source, xmlTimeStamp, xmlTimeStampEnd);
    }
    catch (NotAuthorizedException e) {
      output = notAuthorized;
      output = output.concat(e.toString());
      output = output.concat(cr);
      return output;
    }
    catch (ResourceNotFoundException e) {
      output = resourceNotFound;
      output = output.concat(e.toString());
      output = output.concat(cr);
      return output;
    }
    catch (BadXmlException e) {
      output = badXml;
      output = output.concat(e.toString());
      output = output.concat(cr);
      return output;
    }
    catch (MiscClientException e) {
      output = miscClient;
      output = output.concat(e.toString());
      output = output.concat(cr);
      return output;
    }

    for (int x = 0; x < data.size(); x++) {
      properties = data.get(x).getProperties().getProperty();
      finalOutput.append(data.get(x).getTimestamp());
      finalOutput.append("  Tool: ");
      finalOutput.append(data.get(x).getTool());
      finalOutput.append("  Properties: (");
      for (int y = 0; y < properties.size(); y++) {
        finalOutput.append(properties.get(y).getKey());
        finalOutput.append(" : ");
        finalOutput.append(properties.get(y).getValue());
      }
      finalOutput.append(")\n");
    }
    output += finalOutput;
    return output;
  }
}
